package com.devshephard.jucks.ThreadExecutorPool;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExetor {

    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor1 = new ThreadPoolExecutor(
                3, //核心线程数（不会被关闭的线程数）

                6, //最大线程数，一个任务被提交到线程池以后，首先会找有没有空闲存活线程，如果有则直接将任务交给这个空闲线程来执行
                // ，如果没有则会缓存到工作队列（后面会介绍）中，如果工作队列满了，才会创建一个新线程，然后从工作队列的头部取出一个任务交由新线程来处理，而将刚提交的任务放入工作队列尾部。
                // 线程池不会无限制的去创建新线程，它会有一个最大线程数量的限制，这个数量即由maximunPoolSize指定。

                3, //超时等待时间，一个线程如果处于空闲状态，并且当前的线程数量大于corePoolSize，那么在指定时间后，这个空闲线程会被销毁，这里的指定时间由下一个keepAliveTime参数来设定

                TimeUnit.SECONDS, //超时等待时间的单位

                new LinkedBlockingDeque<>(3),//阻塞队列，用于存储等待中的任务。该阻塞队列已满将会开启最大线程

                Executors.defaultThreadFactory(), //默认的线程工厂一般不变，用于设置创建线程的工厂，可以通过线程工厂给每个创建出来的线程做些更有意义的事情，比如 设定线程名、设置daemon和优先级等等

                new ThreadPoolExecutor.CallerRunsPolicy() //拒绝策略，线程池最大承载数为 maxPoolSize + 阻塞队列长度
                // （AbortPolicy => 当线程最大承载数超出，抛出异常）
                // （CallerRunsPolicy => 当线程最大承载数超出，多余的线程将会被由调用线程执行）
                // （DiscardPolicy => 当线程最大承载数超出，多余的线程将会被放弃任务）
                // （DiscardOldestPolicy => 当线程最大承载数超出，多余的线程将会和最早执行的线程竞争，竞争失败将会放弃任务）
        );


        try{
            /*for (int i = 0; i < 100; i++) {
                threadPoolExecutor1.execute(()->{
                    System.out.println(Thread.currentThread().getName());
                });
            }*/
            threadPoolExecutor1.execute(()->{
                System.out.println(Thread.currentThread().getName());
            });
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPoolExecutor1.shutdown();
        }

    }


}
